use actix_web::error::JsonPayloadError;
use crate::response::api_response::ApiResponse;

use actix_web::{dev::ServiceResponse, http::{header, StatusCode}, middleware::{ErrorHandlerResponse, ErrorHandlers}, web, App, HttpResponse, HttpRequest, Result, error};
use actix_web::body::BoxBody;

// 自定义错误处理
pub async fn handle_json_error(
    err: JsonPayloadError,
    _req: &HttpRequest,
) -> ApiResponse<()> {
    let msg = format!("Json deserialize error: {}", err);
    let response: ApiResponse<()> = ApiResponse {
        code: 1,
        msg: msg.to_string(),
        data: None,
    };
    response
}

// pub fn json_error_handler(err: error::JsonPayloadError, _req: &HttpRequest) -> error::Error {
//     use actix_web::error::JsonPayloadError;
//
//     let mut  response: ApiResponse<BoxBody> = ApiResponse {
//         code: 1,
//         msg:  err.to_string(),
//         data: None,
//     };
//
//     // let resp = match &err {
//     //     JsonPayloadError::ContentType => HttpResponse::UnsupportedMediaType().body(response),
//     //     JsonPayloadError::Deserialize(json_err) if json_err.is_data() => response,
//     //     _ => response,
//     // };
//     error::InternalError::from_response(err, &response).into()
// }
pub fn json_error_handler(err: error::JsonPayloadError, _req: &HttpRequest) -> error::Error {
    use actix_web::error::JsonPayloadError;

    let response = ApiResponse::<()>{ // Specify response type as ApiResponse<()>
        code: 1,
        msg: err.to_string(),
        data: None,
    };

    match &err {
        JsonPayloadError::ContentType => {
            let resp = HttpResponse::UnsupportedMediaType().json(response);
            error::InternalError::from_response(err, resp).into()
        },
        JsonPayloadError::Deserialize(_) => {
            let resp = HttpResponse::BadRequest().json(response);
            error::InternalError::from_response(err, resp).into()
        },
        _ => {
            let resp = HttpResponse::InternalServerError().json(response);
            error::InternalError::from_response(err, resp).into()
        },
    }
}

pub fn add_error_header<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
    res.response_mut().headers_mut().insert(
        header::CONTENT_TYPE,
        header::HeaderValue::from_static("Error"),
    );

    // body is unchanged, map to "left" slot
    Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
}

pub fn handle_bad_request<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
    res.response_mut().headers_mut().insert(
        header::CONTENT_TYPE,
        header::HeaderValue::from_static("Bad Request Error"),
    );

    // body is unchanged, map to "left" slot
    Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
}